#include "xsane.h"
#include "xsane-gamma.h"
#include "xsane-curve.h"
#include "xsane-gammacurve.h"
#include "xsane-gamma-curve-window.h"
#include "xsane-back-gtk.h"

/* ---------------------------------------------------------------------------------------------------------------------- */
/* xsane_gamma_curve_notebook_page_new creates a notebook page with a gamma curve
   of 65536 entries and a value range from 0.0-1.0 */

static GtkWidget* xsane_gamma_curve_notebook_page_new(GtkWidget *notebook, const char *title)
{
 gfloat fmin, fmax, *vector;
 GtkWidget *curve, *gamma, *vbox, *label;
 int  optlen;

  DBG(DBG_proc, "xsane_gamma_curve_notebook_page_new\n");

  optlen = 65536;
  fmin = 0.0;
  fmax = 1.0;

  label = gtk_label_new((char *) title);
  vbox = gtk_vbox_new(/* homogeneous */ FALSE, 0);
  gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox, label);
  gtk_widget_show(vbox);
  gtk_widget_show(label);

  gamma = xsane_gamma_curve_new();
  gtk_widget_set_size_request(gamma, -1, 256);
  curve = XSANE_GAMMA_CURVE(gamma)->curve;

  vector = (gfloat *)alloca(optlen * sizeof(vector[0]));

  xsane_curve_set_range(XSANE_CURVE(curve), 0, optlen - 1, fmin, fmax);
#if 0
  xsane_curve_maintain_accuracy(XSANE_CURVE(curve), 1.0);
#endif

  gtk_container_set_border_width(GTK_CONTAINER(gamma), 4);
  gtk_box_pack_start(GTK_BOX(vbox), gamma, TRUE, TRUE, 0);
  gtk_widget_show(gamma);

  return gamma;
}                   

/* ---------------------------------------------------------------------------------------------------------------------- */

void xsane_update_gamma_dialog()
{
  DBG(DBG_proc, "xsane_update_gamma_dialog\n");

  if (preferences.show_gamma)
  {
    gtk_widget_show(xsane.free_gamma.window);
  }
}


/* ---------------------------------------------------------------------------------------------------------------------- */

static gint xsane_gamma_win_delete(GtkWidget *widget, gpointer data)
{
  DBG(DBG_proc, "xsane_gamma_win_delete\n");

  gtk_widget_hide(widget);
  preferences.show_gamma = FALSE;
  gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.show_gamma_widget), preferences.show_gamma);
  return TRUE;
}                                    

static void xsane_curve_type_changed_callback(GtkWidget *widget, gpointer data)
{
  DBG(DBG_proc, "xsane_curve_type_changed_callback\n");

  if (xsane.always_auto_enhance)
    xsane_auto_enhance();
  else
    xsane_enhancement_by_histogram(TRUE);
}

/* ---------------------------------------------------------------------------------------------------------------------- */


static guint  gamma_curve_timer; /* has to be guint */
static int    gamma_curve_timer_restart;

static gboolean xsane_curve_hold_event(gpointer ptr)
{
  DBG(DBG_proc, "xsane_curve_hold_event\n");

  if (xsane.always_auto_enhance)
    xsane_auto_enhance();
  else
    xsane_enhancement_by_histogram(TRUE);

  gtk_timeout_remove(gamma_curve_timer);
  gamma_curve_timer = 0;

  if (gamma_curve_timer_restart)
  {
    gamma_curve_timer = gtk_timeout_add(XSANE_CONTINUOUS_HOLD_TIME, xsane_curve_hold_event, 0);
    gamma_curve_timer_restart = FALSE;
  }

 return FALSE;
}
static int xsane_curve_events_callback(GtkWidget *widget, GdkEvent *event, gpointer data)
{
 GdkEventMotion *motion_event;
 static int update = FALSE;

  DBG(DBG_proc, "xsane_curve_events_callback\n");

  switch(event->type)
  {
    case GDK_BUTTON_PRESS:
      update = TRUE;
     break;
    
    case GDK_BUTTON_RELEASE:
      if (xsane.always_auto_enhance)
        xsane_auto_enhance();
      else
        xsane_enhancement_by_histogram(TRUE);
      update = FALSE;
     break;

    case GDK_MOTION_NOTIFY:
      motion_event = (GdkEventMotion *) event;
      update = TRUE;
     break;

    default:
     break;
  }

  if (update)
  {
    update = FALSE;

    if (preferences.gtk_update_policy == GTK_UPDATE_CONTINUOUS)
    {
      /* call xsane_enhancement_by_histogram by event handler */
      if (!gamma_curve_timer)
      {
        gamma_curve_timer = gtk_timeout_add(XSANE_CONTINUOUS_HOLD_TIME, xsane_curve_hold_event, 0);
      }
      else
      {
        gamma_curve_timer_restart = TRUE;
      }
    }
    else if (preferences.gtk_update_policy == GTK_UPDATE_DELAYED)
    {
      if (gamma_curve_timer) /* hold timer active? then remove it, we had a motion */
      {
        gtk_timeout_remove(gamma_curve_timer);
      }          
      /* call xsane_curve_hold_event if mouse is not moved for ??? ms */
      gamma_curve_timer = gtk_timeout_add(XSANE_HOLD_TIME, xsane_curve_hold_event, 0);
    }
  }

 return 0;
}

/* ---------------------------------------------------------------------------------------------------------------------- */

#define XSANE_GAMMA_POS_X 100
#define XSANE_GAMMA_POS_Y 100

void xsane_create_gamma_dialog(const char *devicetext)
{
 char windowname[TEXTBUFSIZE];
 GtkWidget *xsane_vbox_gamma, *notebook;

  DBG(DBG_proc, "xsane_create_free_gamma_dialog\n");

  xsane.free_gamma.window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_resizable(GTK_WINDOW(xsane.free_gamma.window), FALSE);
  gtk_window_move(GTK_WINDOW(xsane.free_gamma.window), XSANE_GAMMA_POS_X, XSANE_GAMMA_POS_Y);
  g_signal_connect(GTK_OBJECT(xsane.free_gamma.window), "delete_event", GTK_SIGNAL_FUNC(xsane_gamma_win_delete), NULL);
  sprintf(windowname, "%s %s", WINDOW_GAMMA, devicetext);
  gtk_window_set_title(GTK_WINDOW(xsane.free_gamma.window), windowname);
  xsane_set_window_icon(xsane.free_gamma.window, 0);
  gtk_window_add_accel_group(GTK_WINDOW(xsane.free_gamma.window), xsane.accelerator_group);

  xsane_vbox_gamma = gtk_vbox_new(TRUE, 5);
  gtk_container_set_border_width(GTK_CONTAINER(xsane_vbox_gamma), 5);
  gtk_container_add(GTK_CONTAINER(xsane.free_gamma.window), xsane_vbox_gamma);
  gtk_widget_show(xsane_vbox_gamma);

  notebook = gtk_notebook_new();
  gtk_container_set_border_width(GTK_CONTAINER(notebook), 4);
  gtk_box_pack_start(GTK_BOX(xsane_vbox_gamma), notebook, TRUE, TRUE, 0);   
  gtk_widget_show(notebook);

  xsane.free_gamma.gray_curve_widget  = xsane_gamma_curve_notebook_page_new(notebook, "Gamma gray");
  xsane.free_gamma.gray_curve_type_changed_handler_id
    = g_signal_connect(GTK_OBJECT(XSANE_GAMMA_CURVE(xsane.free_gamma.gray_curve_widget)->curve),
        "curve-type-changed",
        G_CALLBACK(xsane_curve_type_changed_callback),
        XSANE_GAMMA_CURVE(xsane.free_gamma.gray_curve_widget)->curve);
  g_signal_connect(GTK_OBJECT(XSANE_GAMMA_CURVE(xsane.free_gamma.gray_curve_widget)->curve),
      "event",
      GTK_SIGNAL_FUNC(xsane_curve_events_callback),
      XSANE_GAMMA_CURVE(xsane.free_gamma.gray_curve_widget)->curve);

  xsane.free_gamma.red_curve_widget   = xsane_gamma_curve_notebook_page_new(notebook, "Gamma red");
  xsane.free_gamma.red_curve_type_changed_handler_id
    = g_signal_connect(GTK_OBJECT(XSANE_GAMMA_CURVE(xsane.free_gamma.red_curve_widget)->curve),
        "curve-type-changed",
        G_CALLBACK(xsane_curve_type_changed_callback),
        XSANE_GAMMA_CURVE(xsane.free_gamma.red_curve_widget)->curve);
  g_signal_connect(GTK_OBJECT(XSANE_GAMMA_CURVE(xsane.free_gamma.red_curve_widget)->curve),
      "event",
      GTK_SIGNAL_FUNC(xsane_curve_events_callback),
      XSANE_GAMMA_CURVE(xsane.free_gamma.red_curve_widget)->curve);

  xsane.free_gamma.green_curve_widget = xsane_gamma_curve_notebook_page_new(notebook, "Gamma green");
  xsane.free_gamma.green_curve_type_changed_handler_id
    = g_signal_connect(GTK_OBJECT(XSANE_GAMMA_CURVE(xsane.free_gamma.green_curve_widget)->curve),
        "curve-type-changed",
        G_CALLBACK(xsane_curve_type_changed_callback),
        XSANE_GAMMA_CURVE(xsane.free_gamma.green_curve_widget)->curve);
  g_signal_connect(GTK_OBJECT(XSANE_GAMMA_CURVE(xsane.free_gamma.green_curve_widget)->curve),
      "event",
      GTK_SIGNAL_FUNC(xsane_curve_events_callback),
      XSANE_GAMMA_CURVE(xsane.free_gamma.green_curve_widget)->curve);

  xsane.free_gamma.blue_curve_widget  = xsane_gamma_curve_notebook_page_new(notebook, "Gamma blue");
  xsane.free_gamma.blue_curve_type_changed_handler_id
    = g_signal_connect(GTK_OBJECT(XSANE_GAMMA_CURVE(xsane.free_gamma.blue_curve_widget)->curve),
        "curve-type-changed",
        G_CALLBACK(xsane_curve_type_changed_callback),
        XSANE_GAMMA_CURVE(xsane.free_gamma.blue_curve_widget)->curve);
  g_signal_connect(GTK_OBJECT(XSANE_GAMMA_CURVE(xsane.free_gamma.blue_curve_widget)->curve),
      "event",
      GTK_SIGNAL_FUNC(xsane_curve_events_callback),
      XSANE_GAMMA_CURVE(xsane.free_gamma.blue_curve_widget)->curve);
}

